﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Sio.Mdm.Utils.Collections
{
    /// <summary>
    /// Various operations that can be done with collections
    /// </summary>
    static public class Operations
    {
        #region Methods

        #region Public

        #region Intersect
        /// <summary>
        /// Intersect two lists
        /// </summary>
        /// <typeparam name="T">Type stored in list</typeparam>
        /// <param name="list1"></param>
        /// <param name="list2"></param>
        /// <returns>Intersected list</returns>
        public static BaseList<T> Intersect<T>(BaseList<T> list1, BaseList<T> list2)
        {
            BaseList<T> result = new BaseList<T>();

            foreach (T item in list1)
            {
                if (list2.Contains(item))
                {
                    result.Add(item);
                }
            }

            return result;
        }
        /// <summary>
        /// Intersect two dictionaries.
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dict1"></param>
        /// <param name="dict2"></param>
        /// <returns>Dictionary with keys contained in both dictionaries</returns>
        public static BaseDictionary<TKey, TValue> Intersect<TKey, TValue>(BaseDictionary<TKey, TValue> dict1, BaseDictionary<TKey, TValue> dict2)
        {
            BaseDictionary<TKey, TValue> result = new BaseDictionary<TKey, TValue>();

            foreach (KeyValuePair<TKey, TValue> item in dict1)
            {
                if (dict2.ContainsKey(item.Key))
                {
                    result.Add(item.Key, item.Value);
                }
            }

            return result;
        }
        /// <summary>
        /// Intersect two hybrid collections
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dict1"></param>
        /// <param name="dict2"></param>
        /// <returns></returns>
        public static IndexedDictionary<TKey, TValue> Intersect<TKey, TValue>(IndexedDictionary<TKey, TValue> dict1, IndexedDictionary<TKey, TValue> dict2)
        {
            IndexedDictionary<TKey, TValue> result = new IndexedDictionary<TKey, TValue>();

            foreach (TKey key in dict1.Keys)
            {
                if (dict2.ContainsKey(key))
                {
                    result.Add(key, dict1[key]);
                }
            }

            return result;
        } 
        #endregion

        #region Uninon
        /// <summary>
        /// Unite items from two lists
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list1"></param>
        /// <param name="list2"></param>
        /// <returns></returns>
        public static BaseList<T> Union<T>(BaseList<T> list1, BaseList<T> list2)
        {
            BaseList<T> result = new BaseList<T>(list1);
            result.AddRange(list2);
            return result;
        }
        /// <summary>
        /// Unite items from two dictionaries
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dict1"></param>
        /// <param name="dict2"></param>
        /// <returns></returns>
        public static BaseDictionary<TKey, TValue> Union<TKey, TValue>(BaseDictionary<TKey, TValue> dict1, BaseDictionary<TKey, TValue> dict2)
        {
            BaseDictionary<TKey, TValue> result = new BaseDictionary<TKey, TValue>(dict1);
            
            foreach (TKey key in dict2.Keys)
            {
                if (!result.ContainsKey(key))
                {
                    result.Add(key, dict2[key]);
                }
            }

            return result;
        }
        /// <summary>
        /// Unite items from two indexed dictionaries
        /// </summary>
        /// <typeparam name="TKey"></typeparam>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="dict1"></param>
        /// <param name="dict2"></param>
        /// <returns></returns>
        public static IndexedDictionary<TKey, TValue> Union<TKey, TValue>(IndexedDictionary<TKey, TValue> dict1, IndexedDictionary<TKey, TValue> dict2)
        {
            IndexedDictionary<TKey, TValue> result = new IndexedDictionary<TKey, TValue>();
            
            foreach (TKey key in dict1.Keys)
            {
                result.Add(key, dict1[key]);
            }

            foreach (TKey key in dict2.Keys)
            {
                if (!result.ContainsKey(key))
                {
                    result.Add(key, dict2[key]);
                }
            }

            return result;
        }
        #endregion

        #endregion

        #endregion
    }
}
